Skip to main content

Overview

Duet uses Cloudflare Sandboxes (container-based Durable Objects) to provide isolated, secure command execution environments. Each room gets its own dedicated sandbox instance that persists for the lifetime of the room.

Sandbox Architecture

Sandboxes are implemented as container-based Durable Objects:
Source: ~/workspace/source/cf-worker/wrangler.toml:6-21 Each sandbox:
  • Runs in an isolated container environment
  • Has its own filesystem state
  • Is bound to a specific room via naming convention
  • Persists across multiple command executions

Sandbox Naming

Sandboxes are named using the pattern sandbox-{roomId}:
Source: ~/workspace/source/cf-worker/index.ts:196 This ensures:
  • Each room has its own isolated sandbox
  • Multiple users in the same room share the same sandbox
  • Different rooms cannot access each other’s sandboxes

Command Execution

Direct Execution Endpoint

The /sandbox/exec endpoint allows direct command execution:
Source: ~/workspace/source/cf-worker/index.ts:210-242

Request Validation

Commands are validated using Zod schema:
Source: ~/workspace/source/cf-worker/index.ts:14-16

Execution Result

Sandbox execution returns stdout and stderr:
The result structure:
Source: ~/workspace/source/internal/ai/client.go:54-65

AI-Triggered Execution

The AI can trigger sandbox commands automatically using <run> tags:
Source: ~/workspace/source/cf-worker/index.ts:185-208 The execution flow:
  1. Extract commands - Regex finds all <run>...</run> tags
  2. Execute each command - Run in the room’s sandbox
  3. Capture output - Get first 500 chars of stdout/stderr
  4. Append to response - Add output after AI’s explanation
  5. Remove tags - Strip <run> tags from final response

Output Truncation

To prevent response bloat, output is limited:
Source: ~/workspace/source/cf-worker/index.ts:199-200 This ensures:
  • Responses remain reasonably sized
  • Users see immediate feedback
  • Long outputs don’t overwhelm the UI

Error Handling

Execution errors are caught and included in the response:
Source: ~/workspace/source/cf-worker/index.ts:195-205 Errors are displayed to the user rather than failing silently.

Sandbox Lifecycle

Creation

Sandboxes are created on-demand when first accessed:
The getSandbox function from @cloudflare/sandbox handles lazy initialization.

Persistence

Sandboxes persist across multiple command executions, maintaining:
  • Filesystem state
  • Working directory
  • Installed packages or files
This allows multi-step workflows like:
  1. Create a file
  2. Modify it
  3. Run it

Cleanup

When a room is deleted, its sandbox is destroyed:
Source: ~/workspace/source/cf-worker/index.ts:244-266 Cleanup errors are collected and returned with a 207 Multi-Status response.

Client API

The Go client provides a method to execute commands:
Source: ~/workspace/source/internal/ai/client.go:128-162

Example Usage

Direct Command Execution

Response:

AI-Triggered Execution

User: “Create a hello.txt file with ‘Hello World’” AI Response:
Final Response to User:

Next Steps